package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"time"

	"github.com/go-xorm/xorm"
)

// 全局XORM引擎（供接口使用）
var globalEngine *xorm.Engine

// InitHTTPHandler 初始化HTTP接口（优化跨域处理，确保所有接口都能正确响应跨域请求）
func InitHTTPHandler(engine *xorm.Engine) {
	globalEngine = engine

	// 1. 先定义通用CORS中间件（确保所有接口都经过跨域处理，避免路由匹配问题）
	corsMiddleware := func(next http.HandlerFunc) http.HandlerFunc {
		return func(w http.ResponseWriter, r *http.Request) {
			// 允许所有源跨域（生产环境可替换为具体前端域名，如"http://127.0.0.1:5500"）
			w.Header().Set("Access-Control-Allow-Origin", "*")
			// 允许的请求方法
			w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
			// 允许的请求头
			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
			// 预检请求直接返回200
			if r.Method == "OPTIONS" {
				w.WriteHeader(http.StatusOK)
				return
			}
			// 执行后续接口逻辑
			next(w, r)
		}
	}

	// 2. 注册接口并绑定CORS中间件（确保每个接口都能处理跨域）
	http.HandleFunc("/api/get-pv", corsMiddleware(getPVHandler))
	http.HandleFunc("/api/get-framework", corsMiddleware(getFrameworkHandler))
	http.HandleFunc("/api/get-ua", corsMiddleware(getUAHandler))

	// 3. 根路径默认返回404（避免无效请求）
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprint(w, "404 Not Found")
	})

	// 打印启动日志
	fmt.Println("==================================")
	fmt.Println("HTTP服务启动成功")
	fmt.Println("监听端口: 8080")
	fmt.Println("接口列表：")
	fmt.Println("  GET /api/get-pv        - 获取最近12小时PV趋势")
	fmt.Println("  GET /api/get-framework  - 获取最新小时框架分布")
	fmt.Println("  GET /api/get-ua         - 获取最新小时UA分布")
	fmt.Println("==================================")
}

// getPVHandler 获取最近12小时PV统计（补充日志打印，方便排查数据来源）
func getPVHandler(w http.ResponseWriter, r *http.Request) {
	type PVData struct {
		Time  string `json:"time"`  // 时间（格式：15:00）
		Value int    `json:"value"` // PV值
	}
	var pvList []PVData

	now := time.Now()
	fmt.Printf("[%s] 收到PV查询请求，查询最近12小时数据\n", now.Format("2006-01-02 15:04:05"))

	// 循环查询最近12小时（i从11到0，确保只查12个小时，无时间重复）
	for i := 11; i >= 0; i-- {
		// 计算当前小时的起始时间（如：16:30 → 16:00:00）
		statTime := now.Add(-time.Duration(i) * time.Hour).Truncate(1 * time.Hour)
		statTimeStr := statTime.Format("2006-01-02 15:00:00") // 完整时间格式，避免日期跨天匹配问题

		var stat TrafficStat
		// 按"完整时间+类型+key"查询，避免同小时不同日期的数据混淆
		has, err := globalEngine.Where(
			"DATE_FORMAT(stat_time, '%Y-%m-%d %H:00:00') = ? AND stat_type = ? AND stat_key = ?",
			statTimeStr, "pv", "total",
		).Get(&stat)

		// 错误处理（打印具体错误，方便排查数据库问题）
		if err != nil {
			errMsg := fmt.Sprintf("查询%s PV数据失败：%v", statTimeStr, err)
			fmt.Println(errMsg)
			http.Error(w, errMsg, http.StatusInternalServerError)
			return
		}

		// 确定当前小时的PV值
		value := 0
		if has {
			value = stat.StatValue
			fmt.Printf("  %s PV值：%d\n", statTimeStr, value)
		} else {
			fmt.Printf("  %s 无PV统计数据，默认返回0\n", statTimeStr)
		}

		// 添加到返回列表（时间格式简化为"15:00"，方便前端显示）
		pvList = append(pvList, PVData{
			Time:  statTime.Format("15:00"),
			Value: value,
		})
	}

	// 返回JSON数据（设置正确的Content-Type）
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	response := map[string]interface{}{
		"code": 0,
		"msg":  "PV查询成功",
		"data": pvList,
	}
	// 编码错误处理（避免 panic）
	if err := json.NewEncoder(w).Encode(response); err != nil {
		fmt.Printf("PV响应数据编码失败：%v\n", err)
		http.Error(w, "数据返回失败", http.StatusInternalServerError)
	}
}

// getFrameworkHandler 获取最新小时框架分布（优化时间查询，避免跨天问题）
func getFrameworkHandler(w http.ResponseWriter, r *http.Request) {
	type FrameworkData struct {
		Name  string `json:"name"`  // 框架名（如：Vue、React）
		Value int    `json:"value"` // 访问次数
	}
	var frameworkList []FrameworkData

	// 获取最新小时的完整起始时间（如：2024-05-20 16:00:00）
	latestHour := time.Now().Truncate(1 * time.Hour)
	latestHourStr := latestHour.Format("2006-01-02 15:00:00")
	fmt.Printf("[%s] 收到框架分布查询请求，查询%s数据\n", time.Now().Format("2006-01-02 15:04:05"), latestHourStr)

	// 查询最新小时的框架统计数据
	var stats []TrafficStat
	err := globalEngine.Where(
		"DATE_FORMAT(stat_time, '%Y-%m-%d %H:00:00') = ? AND stat_type = ?",
		latestHourStr, "framework",
	).Find(&stats)

	if err != nil {
		errMsg := fmt.Sprintf("查询框架分布数据失败：%v", err)
		fmt.Println(errMsg)
		http.Error(w, errMsg, http.StatusInternalServerError)
		return
	}

	// 格式化数据（统计总次数，避免空数据）
	total := 0
	for _, stat := range stats {
		frameworkList = append(frameworkList, FrameworkData{
			Name:  stat.StatKey,
			Value: stat.StatValue,
		})
		total += stat.StatValue
	}
	fmt.Printf("  最新小时框架统计：共%d次访问，框架数：%d\n", total, len(frameworkList))

	// 返回响应
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"code": 0,
		"msg":  "框架分布查询成功",
		"data": frameworkList,
	})
}

// getUAHandler 获取最新小时UA分布（优化UA简化逻辑，补充日志）
func getUAHandler(w http.ResponseWriter, r *http.Request) {
	type UAData struct {
		Name  string `json:"name"`  // 简化UA名（如：Chrome、Firefox）
		Value int    `json:"value"` // 访问次数
	}
	var uaList []UAData

	// 获取最新小时的完整起始时间
	latestHour := time.Now().Truncate(1 * time.Hour)
	latestHourStr := latestHour.Format("2006-01-02 15:00:00")
	fmt.Printf("[%s] 收到UA分布查询请求，查询%s数据\n", time.Now().Format("2006-01-02 15:04:05"), latestHourStr)

	// 查询最新小时的UA统计数据
	var stats []TrafficStat
	err := globalEngine.Where(
		"DATE_FORMAT(stat_time, '%Y-%m-%d %H:00:00') = ? AND stat_type = ?",
		latestHourStr, "ua",
	).Find(&stats)

	if err != nil {
		errMsg := fmt.Sprintf("查询UA分布数据失败：%v", err)
		fmt.Println(errMsg)
		http.Error(w, errMsg, http.StatusInternalServerError)
		return
	}

	// 简化UA名并统计（优化匹配逻辑，避免重复归类）
	uaCountMap := make(map[string]int) // 用map避免相同浏览器重复统计
	for _, stat := range stats {
		ua := stat.StatKey
		var browserName string

		// 按优先级匹配浏览器（Chrome包含Safari的标识，需优先匹配Chrome）
		switch {
		case strings.Contains(ua, "Chrome") && !strings.Contains(ua, "Edge"):
			browserName = "Chrome"
		case strings.Contains(ua, "Edge"):
			browserName = "Edge"
		case strings.Contains(ua, "Firefox"):
			browserName = "Firefox"
		case strings.Contains(ua, "Safari"):
			browserName = "Safari"
		default:
			browserName = "Other"
		}

		// 累加相同浏览器的次数
		uaCountMap[browserName] += stat.StatValue
	}

	// 转换为返回列表
	total := 0
	for name, value := range uaCountMap {
		uaList = append(uaList, UAData{
			Name:  name,
			Value: value,
		})
		total += value
	}
	fmt.Printf("  最新小时UA统计：共%d次访问，浏览器类型数：%d\n", total, len(uaList))

	// 返回响应
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"code": 0,
		"msg":  "UA分布查询成功",
		"data": uaList,
	})
}
